//
//  RFCSNValidator.m
//  HPShellTest
//
//  Created by marco on 14/12/19.
//  Copyright (c) 2014年 marco. All rights reserved.
//

#import "RFCSNValidatorController.h"
#import "HPUIEngine.h"
#import "ZZTongClientEngine.h"
#import "HPClientEngine.h"
#import <HandPaySwiperModule/HandPaySwiperModule.h>
#import "ZZTongDefine.h"

@interface RFCSNValidatorController()
{
    int responseEnumMapping[7];
    NSDictionary* errInfoDictionary;
}
@end

@implementation RFCSNValidatorController

+(instancetype)sharedInstance
{
    static RFCSNValidatorController* instance = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

-(instancetype)init
{
    self = [super init];
    errInfoDictionary = @{[NSNumber numberWithInt:CSNStatusLogOut]:@"刷卡器已注销",
                          [NSNumber numberWithInt:CSNStatusLoss]:@"刷卡器已挂失",
                          [NSNumber numberWithInt:CSNStatusBoundOtherChannel]:@"刷卡器已绑定到其他渠道",
                          [NSNumber numberWithInt:CSNStatusBoundOtherUser]:@"刷卡器已绑定到其他用户"};
    return self;
}

-(void)validateCSNComplete:(void(^)(BOOL, NSString*))block
           autoTip:(BOOL)tip
{
    _tip = tip;
    complete = [block copy];
    
    NSString* account = ZZT_CLIENG.accountInfo.account;
    NSString* csn = [HPSwiperContext sharedInstance].connectedDeviceCSN;
    
    if (!account.length)
        [self finishedWithErrMsg:@"用户未登录"];
    else if(!csn)
        [self finishedWithErrMsg:@"请插入刷卡器"];
    else if (![HPUIENG doCheckGPSStatus])
        [self finishedWithErrMsg:LocationErrMsg2];
    else if (!_networkUnAvailable)
        [self checkCSNStatus];
}

-(void)setLocation:(NSString *)location
{
    [location retain];
    if (_location)
        [_location release];
    _location = location;
}

-(void)setAddress:(NSString *)address
{
    [address retain];
    if (_address)
        [_address release];
    _address = address;
}

-(void)setLocationDate:(NSDate *)locationDate
{
    [locationDate retain];
    if (_locationDate)
        [_locationDate release];
    _locationDate = locationDate;
}

- (void)checkCSNStatus
{
    _running = YES;
    _networkUnAvailable = YES;
    [[HPUIEngine getInstance] showWaiting:@"正在加载中..."];
    
    [[HPUIEngine getInstance] getAddressWithGPSBlock:^(NSString *latitude, NSString *longitude, NSString *address, NSError *error)
     {
         if (latitude.length > 0 && longitude.length > 0 && address.length > 0)
         {
             LOG(@"%@ %@ %@",latitude,longitude,address);
             self.location = [NSString stringWithFormat:@"%@,%@",latitude,longitude];
             self.address = address;
             self.locationDate = [NSDate date];
         }
         
         if (self.locationDate && -[self.locationDate timeIntervalSinceNow] < 1200)//20分钟内 可以使用上次的获取的位置
             [self requestValidateSwipeBindInfo];
         else
             [self showDialogLetUserTryAgain];
     }];
}

-(void)requestValidateSwipeBindInfo
{
    NSDictionary* params = @{KEY_ACCOUNT : DES_ENC(ZZT_CLIENG.accountInfo.account),
                             KEY_CSN : DES_ENC([HPSwiperContext sharedInstance].connectedDeviceCSN),
                             KEY_ADDRESS : self.address,
                             KEY_LOCATION: self.location,
                             KEY_CHANNEL : [ZZT_CLIENG getChannel]};
    
    ZZTongNetEngine* netEngin = [ZZTongClientEngine sharedInstance].netEngine;
    [netEngin sendRequest:NET_ACTION_ZZT_GET_SWIPER_STATUS
               withParams:params
             withDelegate:self
              withAddress:APP_URL_NAME
            withAlertFlag:NO];
}

-(void)showDialogLetUserTryAgain
{
    [HPUIENG removeWaiting];
    _networkUnAvailable = NO;
    AlertCommandData* commandCancel = [[AlertCommandData alloc]initCommand:@"取消" function:@selector(cancelLocation)];
    AlertCommandData* commandOK = [[AlertCommandData alloc]initCommand:@"再次获取" function:@selector(retryLocation)];
    AlertData* alertData = [[AlertData alloc] initAlertData:self title:@"提示" message:@"获取地理位置失败，请至信号良好处再次获取。" commands:commandCancel,commandOK, nil];
    [HPUIENG showAlertWithData:alertData];
    
    [commandCancel release];
    [commandOK release];
    [alertData release];
}

- (void)cancelLocation
{
    _tip = NO;//定位失败不提示
    [self finishedWithErrMsg:LocationErrMsg];
}

- (void)retryLocation {  [self checkCSNStatus];}

- (void)finishedWithErrMsg:(NSString *)msg
{   // reset status
    _networkUnAvailable = NO;
    _running = NO;
    if (_tip && msg.length)
        [[HPUIEngine getInstance] showAlert:msg];
    
    BOOL isValide = msg == nil;
    complete(isValide, msg);
    complete = nil;
}

- (void)responseCallBackSuccess:(NSString *)action withData:(NSDictionary *)respDat
{
    dispatch_async(dispatch_get_main_queue(), ^{
        [HPUIENG removeWaiting];
        if ([action isEqualToString:NET_ACTION_ZZT_GET_SWIPER_STATUS])
            [self configStatusResponse:respDat];
        else if ([action isEqualToString:NET_ACTION_ZZT_BIND_SWIPER])
            [self parseBindSwiper:respDat];
        _networkUnAvailable = NO;
    });
}

- (void)responseCallBackFailed:(NSString *)action withErrCode:(NSString *)errCode withErrMsg:(NSString *)msg
{
    if ([action isEqualToString:NET_ACTION_ZZT_GET_SWIPER_STATUS])
    {
        [HPUIENG removeWaiting];
        if (msg.length > 0)
            [self finishedWithErrMsg:msg];
        else
            [self finishedWithErrMsg:@"请求刷卡器状态失败"];
    }
    _networkUnAvailable = NO;
}

- (void)configStatusResponse:(NSDictionary *)respData
{
    NSString * status = [respData objectForKey:@"status"];
    NSString * msg = nil;
    id<HPSwipeServiceProtocal> service = [HPSwiperContext sharedInstance].avaliableService;
    
    if (status.length > 0)
    {
        msg = [respData objectForKey:@"message"];
        int enumMapping[7] = {CSNStatusAvailable, CSNStatusUnbound, CSNStatusBoundOtherUser,
                                CSNStatusBoundOtherChannel, CSNStatusLoss, CSNStatusLogOut, CSNStatusNone};
        int stateIdx = status.intValue;
        CSNStatus csnstate = enumMapping[stateIdx];
        [service setCsnStatus:csnstate];
        if (csnstate == CSNStatusAvailable || csnstate == CSNStatusUnbound)
            msg = nil;
    }
    else
    {
        msg = [respData objectForKey:NET_ERROR_MESSAGE];
        if(!msg.length)
            msg = [respData objectForKey:@"message"];
    }
    
    if (!msg.length)
        msg = [self tipsFromCsnStatus];
    [self finishedWithErrMsg:msg];
}

- (NSString *)tipsFromCsnStatus
{
    id<HPSwipeServiceProtocal> service = [HPSwiperContext sharedInstance].avaliableService;
    if (service.csnStatus == CSNStatusAvailable)
        return nil;
    
    NSString* stateInfo = [errInfoDictionary objectForKey:[NSNumber numberWithInt:service.csnStatus]];
    if (service.csnStatus == CSNStatusUnbound)
        return [self processUnboundState];
    
    if(!stateInfo)
        stateInfo = @"刷卡器状态未知";
    return stateInfo;
}

-(NSString*)processUnboundState
{
    if (_tip)//资质提交过程中不提示绑定刷卡器或者资质未提交，有资质提交按钮的页面也不提示
    {
        Screen* screen = [HPUIENG getCurrentScreen];
        if ([screen.screenName isEqualToString:SCR_REGISTER_SUCCESS]||
            [screen.screenName isEqualToString:SCR_QUALITY_CONFIRM] ||
            //                [screen.screenName isEqualToString:SCR_ACCOUNT_INDEX] ||
            [screen.screenName isEqualToString:SCR_QUALITY_INDEX] ||
            [screen.screenName isEqualToString:SCR_QUALITY_PHOTO] ||
            [screen.screenName isEqualToString:SCR_REVIEW_STATE]) {
            _tip = NO;
        }
    }
    
    if (ZZT_CLIENG.accountInfo.accountStatus != AccountStatusNotSubmit)
    {
        if (_tip)
        {
            AlertCommandData* commandCancel = [[AlertCommandData alloc] initCommand:@"取消" function:@selector(doCancel)];
            AlertCommandData* commandBind = [[AlertCommandData alloc] initCommand:@"绑定" function:@selector(doBindCSN)];
            AlertData* alertData = [[AlertData alloc] initAlertData:self title:@"提示" message:@"刷卡器未绑定，需要立即绑定吗？" commands:commandCancel, commandBind, nil];
            [HPUIENG showAlertWithData:alertData];
            complete = nil;
            _tip = NO;
            
            [commandCancel release];
            [commandBind release];
            [alertData release];
        }
        return @"刷卡器未绑定";
    }
    else
    {
        _tip = NO;//不提示资质未提交
        if (_tip)
        {
            AlertCommandData* commandCancel = [[AlertCommandData alloc]initCommand:@"暂不提交"];
            AlertCommandData* commandOK = [[AlertCommandData alloc]initCommand:@"马上提交" function:@selector(submitQuality)];
            
            AlertData* alertData = [[AlertData alloc] initAlertData:ZZT_CLIENG title:@"提示" message:@"资质信息未提交" commands:commandOK,commandCancel, nil];
            [HPUIENG showAlertWithData:alertData];
            complete = nil;
            _tip = NO;
            
            [commandCancel release];
            [commandOK release];
            [alertData release];
        }
        return @"未提交资质信息";
    }
}

- (void)doCancel{}

- (void)doBindCSN
{
    id<HPSwipeServiceProtocal> swipService = [HPSwiperContext sharedInstance].avaliableService;
    ZZTongClientEngine* zzt = ZZT_CLIENG;
    [zzt.uiEngine showNetWaiting];
    
    NSString* tempCsn = swipService.csn;
    NSDictionary* params = @{KEY_CHANNEL : [zzt getChannel],
                             KEY_PHONE : DES_ENC(ZZT_CLIENG.accountInfo.mobile),
                             KEY_CSN : DES_ENC(tempCsn),
                             @"account":DES_ENC(zzt.accountInfo.account)};
    [zzt.netEngine sendRequest:NET_ACTION_ZZT_BIND_SWIPER withParams:params withDelegate:self];
}

- (void)parseBindSwiper:(NSDictionary *)respData
{
    if ([[respData objectForKey:NET_RESPONSE_CODE] isEqualToString:NET_RESPONSE_SUCCESS])
    {
        id<HPSwipeServiceProtocal> swipService = [HPSwiperContext sharedInstance].avaliableService;
        [HPUIENG showAlert:@"绑定成功"];
        [swipService setCsnStatus:CSNStatusNone];
        // recheck.
        complete = nil;
        _tip = NO;
        [self checkCSNStatus];
    }
}

-(void)clearData
{
    _networkUnAvailable = NO;
    _running = NO;
    complete = nil;
    _tip = NO;
}
@end
